/**
 * 前端错误处理工具
 * 用于统一处理API错误和前端异常
 */

// 错误类型常量
export const ERROR_TYPES = {
  NETWORK: 'network_error',
  API: 'api_error',
  VALIDATION: 'validation_error',
  AUTH: 'authentication_error',
  NOT_FOUND: 'not_found_error',
  PERMISSION: 'permission_error',
  SERVER: 'server_error',
  UNKNOWN: 'unknown_error',
  CLIENT: 'client_error',
};

/**
 * 处理API错误
 * @param {Error|Object} error - 错误对象
 * @returns {Object} 格式化的错误对象
 */
export const handleApiError = (error) => {
  // 默认错误信息
  let errorData = {
    type: ERROR_TYPES.UNKNOWN,
    message: '发生未知错误，请稍后再试',
    details: null,
    status: null,
    timestamp: new Date().toISOString(),
  };

  // 如果是Axios错误
  if (error.response) {
    const { status, data } = error.response;
    
    // 根据HTTP状态码确定错误类型
    switch (status) {
      case 400:
        errorData.type = ERROR_TYPES.VALIDATION;
        errorData.message = data.message || '请求数据无效';
        errorData.details = data.errors || data.details;
        break;
      case 401:
        errorData.type = ERROR_TYPES.AUTH;
        errorData.message = '您的登录已过期，请重新登录';
        break;
      case 403:
        errorData.type = ERROR_TYPES.PERMISSION;
        errorData.message = '您没有权限执行此操作';
        break;
      case 404:
        errorData.type = ERROR_TYPES.NOT_FOUND;
        errorData.message = data.message || '请求的资源不存在';
        break;
      case 422:
        errorData.type = ERROR_TYPES.VALIDATION;
        errorData.message = data.message || '提交的数据无效';
        errorData.details = data.errors || data.details;
        break;
      case 500:
      case 502:
      case 503:
        errorData.type = ERROR_TYPES.SERVER;
        errorData.message = '服务器错误，请稍后再试';
        break;
      default:
        errorData.type = ERROR_TYPES.API;
        errorData.message = data.message || '请求处理失败';
    }
    
    errorData.status = status;
    
    // 如果服务器返回了详细错误信息
    if (data.error) {
      errorData.details = data.error;
    }
  } else if (error.request) {
    // 请求已发出但没有收到响应
    errorData.type = ERROR_TYPES.NETWORK;
    errorData.message = '网络连接错误，请检查您的网络连接';
  } else {
    // 设置请求时发生错误
    errorData.type = ERROR_TYPES.CLIENT;
    errorData.message = error.message || '请求配置错误';
  }

  // 记录错误到控制台
  console.error('[API Error]', errorData);

  // 可以在这里添加错误上报逻辑
  // reportErrorToService(errorData);

  return errorData;
};

/**
 * 处理前端应用错误
 * @param {Error} error - 错误对象
 * @param {Object} info - 额外的错误信息
 * @returns {Object} 格式化的错误对象
 */
export const handleAppError = (error, info = {}) => {
  const errorData = {
    type: ERROR_TYPES.CLIENT,
    message: error.message || '应用发生错误',
    stack: error.stack,
    info,
    timestamp: new Date().toISOString(),
  };

  // 记录错误到控制台
  console.error('[App Error]', errorData);

  // 可以在这里添加错误上报逻辑
  // reportErrorToService(errorData);

  return errorData;
};

/**
 * 全局未捕获异常处理
 */
export const setupGlobalErrorHandlers = () => {
  // 处理未捕获的Promise错误
  window.addEventListener('unhandledrejection', (event) => {
    const error = event.reason;
    console.error('[Unhandled Promise Rejection]', error);
    
    // 可以在这里添加错误上报逻辑
    // reportErrorToService({
    //   type: ERROR_TYPES.CLIENT,
    //   message: error.message || '未处理的Promise错误',
    //   stack: error.stack,
    //   timestamp: new Date().toISOString(),
    // });
    
    // 防止默认处理
    event.preventDefault();
  });

  // 处理全局JavaScript错误
  window.addEventListener('error', (event) => {
    console.error('[Global Error]', {
      message: event.message,
      filename: event.filename,
      lineno: event.lineno,
      colno: event.colno,
      error: event.error,
      timestamp: new Date().toISOString(),
    });
    
    // 可以在这里添加错误上报逻辑
    // reportErrorToService({
    //   type: ERROR_TYPES.CLIENT,
    //   message: event.message,
    //   stack: event.error?.stack,
    //   filename: event.filename,
    //   lineno: event.lineno,
    //   colno: event.colno,
    //   timestamp: new Date().toISOString(),
    // });
    
    // 防止默认处理
    event.preventDefault();
  });
};

/**
 * 显示用户友好的错误消息
 * @param {Object} error - 错误对象
 * @returns {String} 用户友好的错误消息
 */
export const getUserFriendlyErrorMessage = (error) => {
  if (!error) return '发生未知错误，请稍后再试';

  // 如果已经是格式化的错误对象
  if (error.type && error.message) {
    return error.message;
  }

  // 处理API错误
  if (error.response) {
    const { status, data } = error.response;
    
    // 根据HTTP状态码返回友好消息
    switch (status) {
      case 400:
        return data.message || '请求数据无效，请检查您的输入';
      case 401:
        return '您的登录已过期，请重新登录';
      case 403:
        return '您没有权限执行此操作';
      case 404:
        return data.message || '请求的资源不存在';
      case 422:
        return data.message || '提交的数据无效，请检查您的输入';
      case 500:
      case 502:
      case 503:
        return '服务器暂时不可用，请稍后再试';
      default:
        return data.message || '请求处理失败，请稍后再试';
    }
  }

  // 处理网络错误
  if (error.request) {
    return '网络连接错误，请检查您的网络连接';
  }

  // 处理其他错误
  return error.message || '发生未知错误，请稍后再试';
};

/**
 * 错误上报服务（示例）
 * @param {Object} errorData - 错误数据
 */
export const reportErrorToService = (errorData) => {
  // 这里可以实现错误上报到服务器或第三方服务
  // 例如Sentry、LogRocket等
  
  // 示例实现
  try {
    const errorLog = {
      ...errorData,
      userAgent: navigator.userAgent,
      url: window.location.href,
      // 可以添加用户信息、应用版本等
    };
    
    // 发送错误日志到服务器
    // fetch('/api/logs/error', {
    //   method: 'POST',
    //   headers: { 'Content-Type': 'application/json' },
    //   body: JSON.stringify(errorLog),
    // });
    
    // 或者使用第三方服务
    // Sentry.captureException(errorData);
  } catch (e) {
    console.error('Error reporting failed:', e);
  }
}; 